package com.niit.mall.mall.gateway.filters;

import com.niit.mall.common.exception.ApiException;
import com.niit.mall.mall.auth.config.AuthProperties;
import com.niit.mall.mall.auth.utils.JwtTool;
import lombok.RequiredArgsConstructor;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;


import java.util.List;

/**
 * @BelongsProject: pardo_mall_backend
 * @BelongsPackage: com.niit.mall.mall.gateway.filters
 * @Author: ChuXuan
 * @CreateTime: 2025-06-05  21:31
 * @Description: Auth拦截器
 * @Version: 1.0
 */
@Component
@RequiredArgsConstructor
public class AuthGlobalFilter implements GlobalFilter, Ordered {
	
	private final JwtTool jwtTool;
	
	private final AuthProperties authProperties;
	
	private final AntPathMatcher antPathMatcher = new AntPathMatcher();
	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		// 1.获取Request
		ServerHttpRequest request = exchange.getRequest();
		// 2.判断是否不需要拦截
		if(isExclude(request.getPath().toString())){
			// 无需拦截，直接放行
			return chain.filter(exchange);
		}
		// 3.获取请求头中的token
		String token = null;
		List<String> headers = request.getHeaders().get("Authorization");
		if (headers != null && !headers.isEmpty()) {
			token = headers.get(0);
		}
		// 4.校验并解析token
		Long userId = null;
		try {
			userId = jwtTool.parseToken(token);
		} catch (ApiException e) {
			// 如果无效，拦截
			ServerHttpResponse response = exchange.getResponse();
			response.setRawStatusCode(401);
			return response.setComplete();
		}
		
		
		// 传递用户信息
		String userInfo = userId.toString();
		ServerWebExchange serverWebExchange = exchange.mutate()
				                                      .request(builder -> builder.header("user-info", userInfo))
				                                      .build();
		// 6.放行
		return chain.filter(serverWebExchange);
	}
	
	private boolean isExclude(String antPath) {
		for (String pathPattern : authProperties.getExcludePaths()) {
			if(antPathMatcher.match(pathPattern, antPath)){
				return true;
			}
		}
		return false;
	}
	
	@Override
	public int getOrder() {
		return 0;
	}
}
